#!/usr/bin/env python
#file: cogent/app/vienna_package.py

"""Application controllers for Vienna Package software.

Revision History

7/12/06 Jeremy Widmann: Added RNAeval
"""

from old_cogent.app.util import CommandLineApplication,\
    CommandLineAppResult, ResultPath
from old_cogent.app.parameters import Parameter, FlagParameter, ValuedParameter,\
    MixedParameter,Parameters, _find_synonym, is_not_None

class RNAfold(CommandLineApplication):
    """Application controller for RNAfold (in the Vienna RNA package)

    Manual on:
    http://www.tbi.univie.ac.at/~ivo/RNA/RNAfold.html
    http://bioweb.pasteur.fr/docs/man/man/RNAfold.1.html

    Parameters with default values:
        -T: 37 (temperature)
        -d: 1 (only unpaired bases in dangling ends)
        -S: 1.07 (scale)

    Input is always written to a file which is used as the application's input.
    StdErr is suppressed by default, but can be overruled in an instance.
    """
    _parameters = {
    '-p':MixedParameter(Prefix='-',Name='p',Delimiter='',Value=False),
    '-C':FlagParameter(Prefix='-',Name='C'),
    '-T':ValuedParameter(Prefix='-',Name='T',Value=37,Delimiter=' '),
    '-4':FlagParameter(Prefix='-',Name=4),
    '-d':MixedParameter(Prefix='-',Name='d',Delimiter='',Value=1),
    '-noLP':FlagParameter(Prefix='-',Name='noLP'),
    '-noGU':FlagParameter(Prefix='-',Name='noGU'),
    '-noCloseGU':FlagParameter(Prefix='-',Name='noCloseGU'),
    '-e':ValuedParameter(Prefix='-',Name='e',Delimiter=' '),
    '-P':ValuedParameter(Prefix='-',Name='P',Delimiter=' '),
    '-nsp':ValuedParameter(Prefix='-',Name='nsp',Delimiter=' '),
    '-S':ValuedParameter(Prefix='-',Name='S',Value=1.07,Delimiter=' ')}
    _synonyms = {'Temperature':'-T','Temp':'-T','Scale':'-S'}
    _command = 'RNAfold'
    _input_handler = '_input_as_lines'
    _suppress_stderr = True 

    def _input_as_string(self,filename):
        """Returns '>filename' to redirect input to stdin"""
        return ''.join(['<',super(RNAfold,self)._input_as_string(filename)])
    
    def _input_as_lines(self,data):
        """Returns '>temp_filename to redirect input to stdin"""
        return ''.join(['<',super(RNAfold,self)._input_as_lines(data)])

    def _get_result_paths(self,data):
        """Specifies the paths of output files generated by the application
        
        data: the data the instance of the application is called on

        You always get back: StdOut,StdErr, and ExitStatus
        RNAfold can produce two additional output files:
            a secondary structure structure graph. Default name: rna.ps
            a dot plot of the base pairing matrix. Default name: dp.ps
        The default names are used for unnamed sequences. Files are created
            in the current working directory.
        You can make a sequence named by inserting a line '>name' above it in
            your input file (or list of sequences). The ss and dp files for 
            named sequences will be written to name_ss.ps and name_dp.ps
        """
        result = {}
        name_counter = 0
        seq_counter = 0
        if not isinstance(data,list):
            #means data is file
            data = open(data).readlines()
        for item in data:
            if item.startswith('>'):
                name_counter += 1
                name = item.strip('>\n')
                result[(name+'_ss')] =\
                    ResultPath(Path=(self.WorkingDir+name+'_ss.ps'))
                result[(name+'_dp')] =\
                    ResultPath(Path=(self.WorkingDir+name+'_dp.ps'),\
                    IsWritten=self.Parameters['-p'].isOn())
            else:
                seq_counter += 1
        
        result['SS'] = ResultPath(Path=self.WorkingDir+'rna.ps',\
            IsWritten=seq_counter - name_counter > 0) #Secondary Structure
        result['DP'] = ResultPath(Path=self.WorkingDir+'dot.ps',
            IsWritten=(self.Parameters['-p'].isOn() and\
            seq_counter - name_counter > 0)) #DotPlot
        return result

class RNAeval(CommandLineApplication):
    """Application controller for RNAfold (in the Vienna RNA package)

    Manual on:
    http://www.tbi.univie.ac.at/~ivo/RNA/RNAfold.html
    http://bioweb.pasteur.fr/docs/man/man/RNAfold.1.html

    Parameters with default values:
        -T: 37 (temperature)
        -d: 1 (only unpaired bases in dangling ends)

    Input is always written to a file which is used as the application's input.
    StdErr is suppressed by default, but can be overruled in an instance.
    """
    _parameters = {
    '-T':ValuedParameter(Prefix='-',Name='T',Value=37,Delimiter=' '),
    '-4':FlagParameter(Prefix='-',Name=4),
    '-d':MixedParameter(Prefix='-',Name='d',Delimiter='',Value=1),
    '-e':ValuedParameter(Prefix='-',Name='e',Delimiter=' '),
    '-P':ValuedParameter(Prefix='-',Name='P',Delimiter=' ')}
    _synonyms = {'Temperature':'-T','Temp':'-T'}
    _command = 'RNAeval'
    _input_handler = '_input_as_lines'
    _suppress_stderr = True 

    def _input_as_string(self,filename):
        """Returns '>filename' to redirect input to stdin"""
        return ''.join(['<',super(RNAeval,self)._input_as_string(filename)])
    
    def _input_as_lines(self,data):
        """Returns '>temp_filename to redirect input to stdin"""
        return ''.join(['<',super(RNAeval,self)._input_as_lines(data)])



class RNAsubopt(CommandLineApplication):
    """Application controller for RNAsubopt (in the Vienna RNA package)

    Manual on:
    http://www.tbi.univie.ac.at/~ivo/RNA/RNAsubopt.html
    http://bioweb.pasteur.fr/docs/man/man/RNAsubopt.1.html

    Parameters with default values:
        -e: 1 (range)
        -T: 37 (temperature)
        -d: 2 (dangling ends as in partition function folding)

    Input is always written to a file which is used as the application's input.
    StdErr is suppressed by default, but can be overwritten in an instance.
    """
    _parameters = {
    '-e':ValuedParameter(Prefix='-',Name='e',Delimiter=' ',Value=1),
    '-ep':ValuedParameter(Prefix='-',Name='ep',Delimiter=' '),
    '-s':FlagParameter(Prefix='-',Name='s'),
    '-lodos':FlagParameter(Prefix='-',Name='lodos'),
    '-T':ValuedParameter(Prefix='-',Name='T',Value=37,Delimiter=' '),
    '-4':FlagParameter(Prefix='-',Name=4),
    '-d':MixedParameter(Prefix='-',Name='d',Delimiter='',Value=2),
    '-noGU':FlagParameter(Prefix='-',Name='noGU'),
    '-noCloseGU':FlagParameter(Prefix='-',Name='noCloseGU'),
    '-P':ValuedParameter(Prefix='-',Name='P',Delimiter=' '),
    '-logML':FlagParameter(Prefix='-',Name='logML'),
    '-nsp':ValuedParameter(Prefix='-',Name='nsp',Delimiter=' '),
    '-noLP':FlagParameter(Prefix='-',Name='noLP')}
    _synonyms = {'Temperature':'-T','Temp':'-T','EnergyRange':'-e','Sort':'-s'}
    _command = 'RNAsubopt'
    _input_handler = '_input_as_lines'
    _suppress_stderr = True 

    def _input_as_string(self,filename):
        """Returns '>filename' to redirect input to stdin"""
        return ''.join(['<',super(RNAsubopt,self)._input_as_string(filename)])
    
    def _input_as_lines(self,data):
        """Returns '>temp_filename to redirect input to stdin"""
        return ''.join(['<',super(RNAsubopt,self)._input_as_lines(data)])
